
package com.smc.common.utils;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringEscapeUtils;

import com.google.common.collect.Lists;
import com.smc.common.exception.BadRequestException;

/**
 * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
 *
 * @author zouqinghua
 * @date 2016年1月25日 下午3:53:08
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {

  private static final char SEPARATOR = '_';
  private static final String CHARSET_NAME = "UTF-8";

  /**
   * 转换为字节数组
   *
   * @param str
   * @return
   */
  public static byte[] getBytes(String str) {
    if (str != null) {
      try {
        return str.getBytes(CHARSET_NAME);
      } catch (UnsupportedEncodingException e) {
        return null;
      }
    } else {
      return null;
    }
  }

  /**
   * 转换为字节数组
   *
   * @param str
   * @return
   */
  public static String toString(byte[] bytes) {
    try {
      return new String(bytes, CHARSET_NAME);
    } catch (UnsupportedEncodingException e) {
      return EMPTY;
    }
  }

  /**
   * 是否包含字符串
   *
   * @param str 验证字符串
   * @param strs 字符串组
   * @return 包含返回true
   */
  public static boolean inString(String str, String... strs) {
    if (str != null) {
      for (String s : strs) {
        if (str.equals(trim(s))) {
          return true;
        }
      }
    }
    return false;
  }

  /** 替换掉HTML标签方法 */
  public static String replaceHtml(String html) {
    if (isBlank(html)) {
      return "";
    }
    String regEx = "<.+?>";
    Pattern p = Pattern.compile(regEx);
    Matcher m = p.matcher(html);
    String s = m.replaceAll("");
    return s;
  }

  /**
   * 替换为手机识别的HTML，去掉样式及属性，保留回车。
   *
   * @param html
   * @return
   */
  public static String replaceMobileHtml(String html) {
    if (html == null) {
      return "";
    }
    return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
  }

  /**
   * 替换为手机识别的HTML，去掉样式及属性，保留回车。
   *
   * @param txt
   * @return
   */
  public static String toHtml(String txt) {
    if (txt == null) {
      return "";
    }
    return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", "&nbsp; &nbsp; ");
  }

  /**
   * 缩略字符串（不区分中英文字符）
   *
   * @param str 目标字符串
   * @param length 截取长度
   * @return
   */
  public static String abbr(String str, int length) {
    if (str == null) {
      return "";
    }
    try {
      StringBuilder sb = new StringBuilder();
      int currentLength = 0;
      for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
        currentLength += String.valueOf(c).getBytes("GBK").length;
        if (currentLength <= length - 3) {
          sb.append(c);
        } else {
          sb.append("...");
          break;
        }
      }
      return sb.toString();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return "";
  }

  public static String abbr2(String param, int length) {
    if (param == null) {
      return "";
    }
    StringBuffer result = new StringBuffer();
    int n = 0;
    char temp;
    boolean isCode = false; // 是不是HTML代码
    boolean isHTML = false; // 是不是HTML特殊字符,如&nbsp;
    for (int i = 0; i < param.length(); i++) {
      temp = param.charAt(i);
      if (temp == '<') {
        isCode = true;
      } else if (temp == '&') {
        isHTML = true;
      } else if (temp == '>' && isCode) {
        n = n - 1;
        isCode = false;
      } else if (temp == ';' && isHTML) {
        isHTML = false;
      }
      try {
        if (!isCode && !isHTML) {
          n += String.valueOf(temp).getBytes("GBK").length;
        }
      } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }

      if (n <= length - 3) {
        result.append(temp);
      } else {
        result.append("...");
        break;
      }
    }
    // 取出截取字符串中的HTML标记
    String temp_result = result.toString().replaceAll("(>)[^<>]*(<?)", "$1$2");
    // 去掉不需要结素标记的HTML标记
    temp_result =
        temp_result.replaceAll(
            "</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>",
            "");
    // 去掉成对的HTML标记
    temp_result = temp_result.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>", "$2");
    // 用正则表达式取出标记
    Pattern p = Pattern.compile("<([a-zA-Z]+)[^<>]*>");
    Matcher m = p.matcher(temp_result);
    List<String> endHTML = Lists.newArrayList();
    while (m.find()) {
      endHTML.add(m.group(1));
    }
    // 补全不成对的HTML标记
    for (int i = endHTML.size() - 1; i >= 0; i--) {
      result.append("</");
      result.append(endHTML.get(i));
      result.append(">");
    }
    return result.toString();
  }

  /** 转换为Double类型 */
  public static Double toDouble(Object val) {
    if (val == null) {
      return 0D;
    }
    try {
      return Double.valueOf(trim(val.toString()));
    } catch (Exception e) {
      return 0D;
    }
  }

  /** 转换为Float类型 */
  public static Float toFloat(Object val) {
    return toDouble(val).floatValue();
  }

  /** 转换为Long类型 */
  public static Long toLong(Object val) {
    return toDouble(val).longValue();
  }

  /** 转换为Integer类型 */
  public static Integer toInteger(Object val) {
    return toLong(val).intValue();
  }

  /** 获得i18n字符串 */
  //    public static String getMessage(String code, Object[] args) {
  //        LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class);
  //        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
  //                .getRequest();
  //        Locale localLocale = localLocaleResolver.resolveLocale(request);
  //        return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale);
  //    }

  /** 获得用户远程地址 */
  public static String getRemoteAddr(HttpServletRequest request) {
    String remoteAddr = request.getHeader("X-Real-IP");
    if (isNotBlank(remoteAddr)) {
      remoteAddr = request.getHeader("X-Forwarded-For");
    } else if (isNotBlank(remoteAddr)) {
      remoteAddr = request.getHeader("Proxy-Client-IP");
    } else if (isNotBlank(remoteAddr)) {
      remoteAddr = request.getHeader("WL-Proxy-Client-IP");
    }
    return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
  }

  /**
   * 驼峰命名法工具
   *
   * @return toCamelCase("hello_world") == "helloWorld" toCapitalizeCamelCase("hello_world") ==
   *     "HelloWorld" toUnderScoreCase("helloWorld") = "hello_world"
   */
  public static String toCamelCase(String s) {
    if (s == null) {
      return null;
    }

    s = s.toLowerCase();

    StringBuilder sb = new StringBuilder(s.length());
    boolean upperCase = false;
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);

      if (c == SEPARATOR) {
        upperCase = true;
      } else if (upperCase) {
        sb.append(Character.toUpperCase(c));
        upperCase = false;
      } else {
        sb.append(c);
      }
    }

    return sb.toString();
  }

  /**
   * 驼峰命名法工具
   *
   * @return toCamelCase("hello_world") == "helloWorld" toCapitalizeCamelCase("hello_world") ==
   *     "HelloWorld" toUnderScoreCase("helloWorld") = "hello_world"
   */
  public static String toCapitalizeCamelCase(String s) {
    if (s == null) {
      return null;
    }
    s = toCamelCase(s);
    return s.substring(0, 1).toUpperCase() + s.substring(1);
  }

  /**
   * 驼峰命名法工具
   *
   * @return toCamelCase("hello_world") == "helloWorld" toCapitalizeCamelCase("hello_world") ==
   *     "HelloWorld" toUnderScoreCase("helloWorld") = "hello_world"
   */
  public static String toUnderScoreCase(String s) {
    if (s == null) {
      return null;
    }

    StringBuilder sb = new StringBuilder();
    boolean upperCase = false;
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);

      boolean nextUpperCase = true;

      if (i < (s.length() - 1)) {
        nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
      }

      if ((i > 0) && Character.isUpperCase(c)) {
        if (!upperCase || !nextUpperCase) {
          sb.append(SEPARATOR);
        }
        upperCase = true;
      } else {
        upperCase = false;
      }

      sb.append(Character.toLowerCase(c));
    }

    return sb.toString();
  }

  /**
   * 如果不为空，则设置值
   *
   * @param target
   * @param source
   */
  public static void setValueIfNotBlank(String target, String source) {
    if (isNotBlank(source)) {
      target = source;
    }
  }

  /**
   * 转换为JS获取对象值，生成三目运算返回结果
   *
   * @param objectString 对象串 例如：row.user.id 返回：!row?'':!row.user?'':!row.user.id?'':row.user.id
   */
  public static String jsGetVal(String objectString) {
    StringBuilder result = new StringBuilder();
    StringBuilder val = new StringBuilder();
    String[] vals = split(objectString, ".");
    for (int i = 0; i < vals.length; i++) {
      val.append("." + vals[i]);
      result.append("!" + (val.substring(1)) + "?'':");
    }
    result.append(val.substring(1));
    return result.toString();
  }

  public static String getMaxLenSubStr(String str, int maxSubstringLength) {
    if (str.length() < maxSubstringLength) {
      return str;
    } else {
      return str.substring(0, maxSubstringLength).concat("......");
    }
  }
  
  /**
   * 将字符进行分割，生成Long类型列表list
   * @param str
   * @param separatorChars 值为 ","
   * @return
   */
  public static List<Integer> splitToIntegerList(String str){
	  return splitToIntegerList(str, ",");
  }
  
  /**
   * 将字符进行分割，生成Integer类型列表list
   * @param str
   * @param separatorChars
   * @return
   */
  public static List<Integer> splitToIntegerList(String str, String separatorChars){
  	List<Integer> list = Lists.newArrayList();
  	/*if(StringUtils.isBlank(separatorChars)){
  		separatorChars = ",";
  	}*/
  	if(StringUtils.isNotBlank(str)){
  		try {
	  		String [] array = str.split(separatorChars);
	  		if(array!=null && array.length>0){
	  			for (String s : array) {
	  				if(StringUtils.isNotBlank(s)){
	  					Integer v = Integer.valueOf(s);
	      				list.add(v);
	  				}
				}
	  		}
  		} catch (Exception e) {
			String message = "参数转换失败  splitToIntegerList , error信息  "+e.getMessage();
			throw new BadRequestException(message);
		}
  	}
  	return list;
  }
  
  
  /**
   * 将字符进行分割，生成Long类型列表list
   * @param str
   * @param separatorChars 值为 ","
   * @return
   */
  public static List<Long> splitToLongList(String str){
	  return splitToLongList(str, ",");
  }
  
  /**
   * 将字符进行分割，生成Long类型列表list
   * @param str
   * @param separatorChars
   * @return
   */
  public static List<Long> splitToLongList(String str, String separatorChars){
  	List<Long> list = Lists.newArrayList();
  	/*if(StringUtils.isBlank(separatorChars)){
			separatorChars = ",";
		}*/
  	if(StringUtils.isNotBlank(str)){
  		try {
  			String [] array = str.split(separatorChars);
  	  		if(array!=null && array.length>0){
  	  			for (String s : array) {
  	  				if(StringUtils.isNotBlank(s)){
  	  					Long v = Long.valueOf(s);
  	      				list.add(v);
  	  				}
  					}
  	  		}
		} catch (Exception e) {
			String message = "参数转换失败  splitToLongList , error信息  "+e.getMessage();
			throw new BadRequestException(message);
		}
  		
  	}
  	return list;
  }
  
  public static List<String> splitToStringList(String str){
	  return splitToStringList(str, ",");
  }
  
  public static List<String> splitToStringList(String str, String separatorChars){
	  List<String> list = Lists.newArrayList();
	  if(StringUtils.isNotBlank(str)){
		  try {
		  		String [] array = str.split(separatorChars);
		  		if(array!=null && array.length>0){
		  			for (String s : array) {
		  				if(StringUtils.isNotBlank(s)){
		      				list.add(s);
		  				}
					}
		  		}
	  		} catch (Exception e) {
				String message = "参数转换失败  splitToStringList , error信息  "+e.getMessage();
				throw new BadRequestException(message);
			}
	  	}
	  return list;
  }
  
  /**首字母大写*/
  public static String captureName(String name) {
      char[] cs=name.toCharArray();
      cs[0]-=32;
      return String.valueOf(cs);
      
  }
  /**处理文件名长度  */
  public static String getSubFileNameByLen(String name,Integer len){
		String fileName = name;
		if(name!=null && name.length()>len){
			String preffix =  name.contains(".")?name.substring(0,name.lastIndexOf(".")):name;
			String suffix = name.contains(".")?name.substring(name.lastIndexOf(".")):"";
			String str = preffix.substring(0, len-suffix.length());
			fileName = str+""+suffix;
		}
		return fileName;
	}
  
  public static byte[] hexStringToByteArray(String s) {
      int len = s.length();
      if ((len & 1) == 1) {
          s = "0" + s;
          len++;
      }
      byte[] data = new byte[len / 2];
      for (int i = 0; i < len; i += 2) {
          data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                  + Character.digit(s.charAt(i + 1), 16));
      }
      return data;
  }
}
